package com.apestech.api.condition.Step;

import com.apestech.framework.db.SqlSession;
import com.apestech.framework.file.callback.VarOperCallBack;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.DBUtil;
import com.apestech.framework.util.LocalVariable;
import com.apestech.framework.util.StringFuncUtil;
import com.apestech.framework.util.StringUtil;
import com.apestech.framework.util.callback.SpiltStrCallback;
import com.apestech.framework.xml.condition.modul.ConditionStrategy;
import java.util.ArrayList;

public class StepUtil extends StringFuncUtil {

    public static JSONObject getInputfields(String inputfields) throws Exception {
        JSONObject m=new JSONObject();
        execSplitStr(inputfields, ",", new SpiltStrCallback(){
            @Override
            public void exec(String id) throws Exception {
                m.put(id,"1");
            }
        });
        return m;
    }

    public JSONObject getAllInput(JSONObject inputMap, JSONObject resultMap, JSONObject resultMap1) throws Exception {
        JSONObject m=new JSONObject();
        m.putAll(inputMap);
        jsonPutAll(m, resultMap);
        jsonPutAll(m, resultMap1);
        return m;
    }

    private void jsonPutAll(JSONObject m, JSONObject dec) throws Exception {
        if(dec==null) return;
        ArrayList<String> klist=dec.getKeylist();
        int len=klist.size();
        for(int i=0; i<len; i++){
            String k=klist.get(i);
            Object value=dec.get(k);
            if(value!=null){
                String scalss=value.getClass().getName();
                if("java.math.BigDecimal".equals(scalss) || "java.lang.Double".equals(scalss)){
                    Object dvalue=m.get(k);
                    if(castToDouble(value)!=0 || dvalue==null){
                        m.put(k, value);
                    }
                } else {
                    m.put(k, value);
                }
            }
        }
    }

    public JSONObject getInputParamFromStr(JSONObject input, ConditionStrategy.Step step) throws Exception {
        if(input==null) throw new Exception("入参数据不可为空！");
        JSONObject map=new JSONObject();
        if(step.getMustInput()!=null && !"".equals(step.getMustInput())){
            execSplitStr(step.getMustInput(), ";", new SpiltStrCallback(){
                @Override
                public void exec(String id) throws Exception {
                    if(input.get(id)!=null){
                        map.put(id, input.get(id));
                    } else if(step.isIsbreak()){
                        String SYS_NO_CHECK=input.getString("SYS_NO_CHECK");
                        if(SYS_NO_CHECK==null || (","+SYS_NO_CHECK+",").indexOf(","+id+",")<0){
                            throw new Exception("所配置必填字段["+id+"]值为空，请检查数据！");
                        }
                    }
                }
            });
            if(input.get("SYS_RQ")!=null) map.put("SYS_RQ", input.get("SYS_RQ"));
            if(input.get("SYS_NO_CHECK")!=null) map.put("SYS_NO_CHECK", input.get("SYS_NO_CHECK"));
            if(input.get("LADDER_NUM")!=null) map.put("LADDER_NUM", input.get("LADDER_NUM"));
            if(step.getOther()!=null) map.putAll(step.getOther());
        } else {
            map.putAll(input);
        }
        return map;
    }

    public void finiExec(JSONObject o, ConditionStrategy.Step step) throws Exception {
        boolean isbreak=false;
        if(step.isIsbreak()){
            if(o==null || o.size()==0 || "1".equals(o.get("sys_break"))){
                isbreak=true;
            }
            else if("1".equals(o.getString("sys_break"))){
                isbreak=true;
            }
        }
        if(!isbreak){
            o.remove("sys_break");
        } else {
            if(step.getNoFoundMsg()!=null){
                throw new Exception(getNoFoundMsg(step));
            } else {
                //throw new Exception("步骤["+step.getName()+"]返回无数据，将退出!");
            }
        }
    }

    public SqlSession getStepDb(String db, SqlSession session) throws Exception {
        if(db==null) return session;
        SqlSession ssession=null;
        if(db.indexOf(".")<0) {
            db = LocalVariable.getProFiles() + "." + db;
        }
        if(session.getDbName().indexOf(db)>=0){
            ssession=session;
        } else {
            ssession=DBUtil.getSession(db);
        }
        if(ssession.getConnection()==null){
            ssession.setConnection(ssession.getDataSource().getConnection());
        }
        return ssession;
    }

    public void closeSession(SqlSession session, SqlSession esession) throws Exception {
        if(!esession.equals(session)){
            esession.closeConnection();
        }
    }

    public String getRealKey(String key, JSONObject sour) throws Exception {
        return getRealKey(key, sour, null);
    }

    public String getRealKey(String key, JSONObject sour, VarOperCallBack varOperCallBack) throws Exception {
        ArrayList<String> vlist=StringUtil.getBatisVariableList(key);
        String v_key=key;
        if(vlist!=null){
            int vlen=vlist.size();
            for(int v=0; v<vlen; v++){
                String varKey=vlist.get(v);
                String rp1="#{"+varKey+"}";
                String rp2=null;
                if(varOperCallBack!=null){
                    rp2=varOperCallBack.getString(varKey);
                } else {
                    rp2=sour.getString(varKey);
                }
                if(rp2!=null){
                    v_key=v_key.replace(rp1, rp2);
                }
            }
            return v_key;
        }
        return null;
    }

    public void setOutputParamFromStr(String field, JSONObject param, JSONObject resultMap) throws Exception {
        if(param==null) return;
        JSONObject finalParam = param;
        execSplitStr(field, ",", new SpiltStrCallback(){
            @Override
            public void exec(String id) throws Exception {
                Object value= finalParam.get(id);
//                if(value==null) value=0;
                if(value!=null){
                    resultMap.put(id, value);
                }
            }
        });
    }

    public void setOutputParamFromField(ArrayList<ConditionStrategy.Field> fields, JSONObject out, JSONObject resultMap, ConditionStrategy conditionStrategy) throws Exception {
        if(out==null) return;
        int len=fields.size();
        for(int i=0; i<len; i++){
            ConditionStrategy.Field f=fields.get(i);
            String id=f.getId();
            if(out==null){
                out=new JSONObject();
            }
            if(out.get(id)!=null){
                if(f.getExpress()!=null) resultMap.put(id, doExpression(f.getExpress(), resultMap, out));
                if(f.getResult()!=null) resultMap.put(id, doExpression(f.getResult(), resultMap, out));
                if(f.getExpress()==null && f.getResult()==null) resultMap.put(id, out.get(id));
            }
            else{
                if(f.getDefaultValue()!=null) resultMap.put(id, f.getDefaultValue());
                else {
                    String dfield=f.getDefaultField();
                    if(dfield!=null){
                        if(dfield.indexOf(".")<0) resultMap.put(id, resultMap.get(dfield));
                        else {
                            String[] list=dfield.split(".");
                            if(list.length!=3) throw new Exception("重复字段名在描述时必须按照这个格式[类型.ID.字段KEY]");
                            String type=list[0].trim();
                            String sid=list[1].trim();
                            String key=list[2].trim();
                            JSONObject r=conditionStrategy.getSteps().get(conditionStrategy.getStepIndex(type+"."+sid)).getResultMap();
                            resultMap.put(id, r.get(key));
                        }
                    }
                }
            }
        }
    }

    public String getNoFoundMsg(ConditionStrategy.Step step){
        String nofound=step.getNoFoundMsg();
        if(nofound==null) return "";
        ArrayList<String> alist=getBatisVariableList(nofound);
        if(alist==null){
            return nofound;
        }
        int alen=alist.size();
        for(int a=0; a<alen; a++){
            String akey=alist.get(a);
            nofound=nofound.replace("#{"+akey+"}", step.getSuperInput().getString(akey));
        }
        return nofound;
    }
}
